package org.example.threadtest;

/**
 * 生产者-消费者模型
 *
 * 修改问题：wait()和notify()需要写在synchronized(){}的同步代码块里面
 */
// 资源
class Res{
    public String username;
    public String sex;
    int count;
    public boolean flag = false; // false时生产者生产,消费者等待;  true时生产者等待,消费者消费

    // 写资源
    public void write() {

        if (count == 0) {
            username = "小红";
            sex = "女";
        } else {
            username = "小军";
            sex = "男";
        }
        // 计算奇数或者偶数
        count = (count + 1) % 2;

    }
    // 读资源
    public void read() {

        System.out.println(Thread.currentThread().getName() + "\t" + username + "," + sex);

    }
}
// 写
class Out extends Thread{

    Res res;

    public Out(Res res) {
        this.res = res;
    }
    @Override
    public void run() {
        // 写操作
        while (true) {
            synchronized (res) { // 对res对象加同步锁
                if (res.flag) { // 如果flag为false，生产者生产；否则等待
                    try {
                        res.wait(); // wait()让当前线程从运行状态变为休眠状态，并且释放锁资源
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName()+"\t开始写资源...");
                res.write();
                res.flag = true;
                res.notify(); // 唤醒被wait()的线程
            }
        }
    }
}
// 读
class Input extends Thread {
    Res res;

    public Input(Res res) {
        this.res = res;
    }
    @Override
    public void run() {
        // 读操作
        while (true) {
            synchronized (res) {
                if (!res.flag) {//如果为flag为false，消费者等待，否则消费
                    try {
                        res.wait(); // wait()让当前线程从运行状态变为休眠状态，并且释放锁资源
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                res.read();
                res.flag = false;
                res.notify(); // 唤醒被wait()的线程
            }
        }
    }
}
public class OutputThread {
    public static void main(String[] args){
        Res res = new Res();
        Out out = new Out(res);
        Input input = new Input(res);
        out.setName("生产者");
        input.setName("消费者");
        out.start();
        input.start();
    }
}
